package com.bart.hsp.scala.ch10.sec08

trait Logger {
  def log(msg: String)
}

trait ConsoleLogger extends Logger {
  def log(msg: String) { println(f"ConsoleLogger -> $msg") }
}

trait ShortLogger extends Logger {
  val maxLength = 15 
  abstract override def log(msg: String) {
    println(f"ShortLogger -> ")
    super.log(
      if (msg.length <= maxLength) msg
      else s"${msg.substring(0, maxLength - 3)}...")
  }
}

class Account {
  protected var balance = 0.0
}

// 只要有一个具体方法即可
/**
 * 为什么打印的是 ShortLogger 是因为
 * SavingsAccount extends 后面的 （Account with ConsoleLogger with ShortLogger） 是一个整体
 * 相当于 Account with （ConsoleLogger with ShortLogger） 这部分
 * 而 ConsoleLogger with ShortLogger 因为特质是从【右】到【左】，
 * 所以实际上是先调用 ShortLogger ，然后再  ShortLogger 中调用 ConsoleLogger 的 log() 方法
 */
class SavingsAccount extends Account with ConsoleLogger with ShortLogger {
  var interest = 0.0
  def withdraw(amount: Double) {
    if (amount > balance) log("Insufficient funds")
    else balance -= amount
  }

  // More methods ...
}

object Main extends App {
  val acct = new SavingsAccount
  acct.withdraw(100)
  acct.maxLength
//  ShortLogger ->
//  ConsoleLogger -> Insufficient...
}

/*

$ javap -private Account.class 
Compiled from "Logger.scala"
public class Account {
  private double balance;
  ...
}

$ javap -private SavingsAccount.class 
Compiled from "Logger.scala"
public class SavingsAccount extends Account implements ConsoleLogger,ShortLogger {
  private double interest;
  private final int maxLength;
  ...
}

*/
